package com.smile.cloud.pay.callback;


import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.smile.cloud.common.base.exception.BizException;
import com.smile.cloud.pay.common.properties.AliPayProperties;
import com.smile.cloud.pay.util.ServletUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@RestController
@ResponseBody
@RequestMapping("/payment/callback")
public class AliPayCallBackUrl {

    private static final String CHARSET = "UTF-8";

    @Autowired
    private AliPayProperties aliPayProperties;

    /**
     * 只有付款成功才会跳转到这里且只跳转一次
     *
     * @return
     */
    @GetMapping("/returnUrl")
    public void returnUrl() {
        try {
            HttpServletResponse response = ServletUtils.getResponse();
            HttpServletRequest request = ServletUtils.getRequest();
            response.setContentType("text/html;charset=" + CHARSET);
            PrintWriter out = response.getWriter();
            //获取支付宝GET过来反馈信息
            boolean signVerified = checkV1(request);

            //——请在这里编写您的程序（以下代码仅作参考）——
            if (signVerified) {
                System.out.println("同步验证成功");
                //商户订单号
                String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");

                //支付宝交易号
                String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");

                //付款金额
                String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "UTF-8");

                out.println("参数如下<br/>&nbsp;&nbsp;&nbsp;&nbsp;out_trade_no : " + out_trade_no + "<br/>&nbsp;&nbsp;&nbsp;&nbsp;trade_no : " + trade_no + "<br/>&nbsp;&nbsp;&nbsp;&nbsp;total_amount : " + total_amount);
            } else {
                out.println("验签回调失败");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (AlipayApiException e) {
            e.printStackTrace();
            throw new BizException(null, "支付宝同步回调");
        }
    }


    /**
     * 服务器通知 :
     * 1. ip地址一定是公网的，私有地址（例如10.2.1.1或者 192.168.1.1）支付宝无法通知到客户端
     * 2. 请求方式是POST请求
     *
     * @return
     */
    @PostMapping("/notyfyUrl")
    public void notyfyUrl() {
        HttpServletResponse response = ServletUtils.getResponse();
        HttpServletRequest request = ServletUtils.getRequest();
        try {
            PrintWriter out = response.getWriter();
            boolean signVerified = checkV1(request);
            if (signVerified) {//验证成功
                System.out.println("异步验证成功");
                //商户订单号
                String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");

                //支付宝交易号
                String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");

                //交易状态
                String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");

                if (trade_status.equals("TRADE_FINISHED")) {
                    //判断该笔订单是否在商户网站中已经做过处理
                    //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                    //如果有做过处理，不执行商户的业务程序
                    System.out.println("订单已完成");
                } else if (trade_status.equals("TRADE_SUCCESS")) {
                    //判断该笔订单是否在商户网站中已经做过处理
                    //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                    //如果有做过处理，不执行商户的业务程序
                    //我们的业务代码
                    System.out.println("订单付款成功");
                }

                out.println("success");

            } else {//验证失败
                out.println("fail");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
    }


    /**
     * 校验签名
     *
     * @param request
     * @return
     * @throws UnsupportedEncodingException
     * @throws AlipayApiException
     */
    private boolean checkV1(HttpServletRequest request) throws UnsupportedEncodingException, AlipayApiException {
        Map<String, String> params = new HashMap<String, String>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用
            valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }

        return AlipaySignature.rsaCheckV1(params, aliPayProperties.getPublicKey(), "UTF-8", "RSA2");
    }

}
